using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;

using InfFront.InfoViews.Base;

namespace InfFront.InfoViews.WinForms
{
    public partial class SourceFrame : BaseFrame
    {
        #region Private Variables
        private InfoViewSource source = null;
        InfoViewEntry curEntry = null;
        #endregion

        #region Construction/Initialization
        public SourceFrame()
        {
            InitializeComponent();
            dgElements.AutoGenerateColumns = false;
        }

        internal void SetSource(InfoViewSource source)
        {
            if (this.source != null)
            {
                this.source.OnRebuilt -= source_Rebuilt;
                this.source.OnListRefreshed -= source_ListRefreshed;
                this.source.OnEditEntry -= source_OnEditEntry;
                this.source.OnCreateEntry -= source_OnCreateEntry;
            }

            this.source = source;
            if (this.source != null)
            {
                this.source.OnRebuilt += source_Rebuilt;
                this.source.OnListRefreshed += source_ListRefreshed;
                this.source.OnEditEntry += source_OnEditEntry;
                this.source.OnCreateEntry += source_OnCreateEntry;
            }

            Rebuild();
        }
        #endregion

        public void Rebuild()
        {
            if (dgElements.DataSource != null)
            {
                dgElements.BindingContext[dgElements.DataSource].PositionChanged -= dgElements_PositionChanged;
                dgElements.DataSource = null;
            }
            dgElements.Columns.Clear();
            toolStrip.Items.Clear();

            if (source == null)
            {
                //dgElements.CaptionText = string.Empty;
                return;
            }

            //dgElements.CaptionText = source.Title;
            BuildToolbar();
            BuildGrid();
        }

        private void BuildGrid()
        {
            foreach (var fld in source.Fields)
            {
                Type type = fld.EffectiveDisplayType;
                DataGridViewColumn col = null;
                if (type.Equals(typeof(string))
                    || type.Equals(typeof(DateTime))
                    || type.Equals(typeof(Int32))
                    || type.Equals(typeof(double))
                   )
                {
                    col = new DataGridViewTextBoxColumn();
                }
                else if (type.Equals(typeof(bool)))
                {
                    col = new DataGridViewCheckBoxColumn(true);
                }
                else
                {
                    throw new NotSupportedException(string.Format("The '{0}' field type '{1}' is not supported", fld.Name, type.Name));
                }

                if (col != null)
                {
                    col.DataPropertyName = fld.Name;
                    col.HeaderText = fld.Title;
                    col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                    col.ReadOnly = fld.IsReadOnly;
                    dgElements.Columns.Add(col);
                }
            }

            dgElements.DataSource = source.GetBindingSource();
            var context = dgElements.BindingContext[dgElements.DataSource];
            context.PositionChanged += dgElements_PositionChanged;
            dgElements_PositionChanged((CurrencyManager)context, EventArgs.Empty);
        }

        private void BuildToolbar()
        {
            foreach (var cmd in source.Commands)
            {
                var button = new Controls.ToolStripButton();
                button.Text = cmd.Title;
                button.Image = cmd.GetIcon(24, 24, false, false);
                button.Tag = cmd;
                button.Click += new EventHandler(toolStripButton_Click);
                toolStrip.Items.Add(button);
            }
        }

        void toolStripButton_Click(object sender, EventArgs e)
        {
            var cmd = ((Controls.ToolStripButton)sender).Tag as InfoViewCommand;
            if (cmd == null)
            {
                Debug.Assert(false, "No InfoViewCommand found");
                return;
            }
            var args = new InfoViewCommand.ExecutionArgs();
            args.CurrentEntry = curEntry;
            cmd.Execute(args);
        }

        void source_Rebuilt(object sender, EventArgs e)
        {
            Rebuild();
        }

        void source_ListRefreshed(object sender, EventArgs e)
        {
            Rebuild();
        }

        void source_OnCreateEntry(object sender, EntryEditEventArgs args)
        {
        }

        void source_OnEditEntry(object sender, EntryEditEventArgs args)
        {
        }

        private void UpdateWithNewCurrentEntry(InfoViewEntry entry)
        {
            if (curEntry != null)
                curEntry.Dispose();
            curEntry = entry;
            int i = 0;
            foreach (bool cmdEnabled in source.CheckCommandsEnabled(entry))
            {
                var btn = (InfFront.InfoViews.WinForms.Controls.ToolStripButton)toolStrip.Items[i++];
                btn.Enabled = cmdEnabled;
            }
        }

        void dgElements_PositionChanged(object sender, EventArgs e)
        {
            if (source == null) // the grid is being cleared
                return;
            InfoViewEntry entry = null;
            var cman = (CurrencyManager)sender;
            if (cman.Position >= 0 &&  cman.Current != null)
                entry = source.ExtractEntry(cman.Current);
            UpdateWithNewCurrentEntry(entry);
        }

    }
}
